Skip to content
lab components / Tables and lists

Action list

List-content of the ActionMenu, that can be used independently.

This is a Lab component!

That means it doesn't satisfy our definition of done and may be changed or even deleted. For an exact status, please reach out to the Fancy team through the dev_fancy or ux_fancy channels.

import { ActionList } from "@siteimprove/fancylab";

#Examples

The inner list content of the ActionMenu component.

#Basic usage

<ActionList items={[ { text: "Actionbutton", onClick: () => console.log("clicked") }, { text: "ActionLink", href: "https://www.google.com", openNew: true }, ActionList.divider, { text: "Disabled actionbutton", onClick: () => console.log("clicked"), disabled: true, }, ActionList.sectionHeader("New section"), { text: "Actionbutton", onClick: () => console.log("clicked"), }, ]} />

#Searchable

The search field allows the user to type in a keyword to search for an item, and it should only be used if the user is very familiar with the menu item. This way the user can access it quickly.

<ActionList searchable items={[ // without icons ActionList.sectionHeader("File"), { text: "New File", onClick: () => console.log("clicked") }, { text: "Open File", onClick: () => console.log("clicked") }, // with icons ActionList.sectionHeader("Settings", <IconSettings />), { text: "Increase Contrast", icon: <IconContrast />, onClick: () => console.log("clicked"), }, { text: "Toggle Fullscreen", description: "this is a description", icon: <IconFullscreen />, onClick: () => console.log("clicked"), }, ]} />

#Custom item

If you want to render a list item differently than the provided ActionItem, LinkItem, Divider and SectionHeader, you can use the render function.

The function passes the same SharedProps that the item possesses, with the notable difference that the text prop has type JSX.Element, since it return a TextHighlight element.

By passing and using such props as text within your custom item, the search field can search within your custom items as well.

<ActionList searchable items={[ { text: "My custom button", description: "This is a custom button", onClick: () => console.log("clicked"), render: (props) => <BigSmall big={props.text} small={props.description} />, }, { text: "My unstyled button", noStyling: true, onClick: () => console.log("clicked"), }, { text: "My custom link", href: "https://www.google.com", openNew: true, render: (props) => ( <div style={{ display: "flex", alignItems: "center", gap: "5px" }}> <InlineText style={{ color: "var(--color--blue)" }}>{props.text}</InlineText> <Icon> <IconOpenNew /> </Icon> </div> ), }, { text: "My unstyled link", noStyling: true, href: "https://www.google.com", openNew: true, }, { text: "My custom content", disabled: true, render(props) { return ( <div> <p>{props.text}</p> </div> ); }, }, ]} />

#Custom renderer

If you want to render all list items differently, you can pass the itemRenderer function.

The function passes the props from ListOptionItem, which is ActionItem | LinkItem | CustomItem

const items = [ { text: "First link", href: "https://www.google.com", count: 1, }, { text: "Second link", href: "https://www.google.com", count: 2, }, ]; return ( <ActionList items={items} itemRenderer={(props) => { const item = props.item as LinkItem & { count: number }; return ( <LinkContainer tabIndex={-1} href={item.href} style={{ width: "100%", padding: "10px", display: "flex", justifyContent: "space-between", }} > <LinkContainer.LinkText>{item.text}</LinkContainer.LinkText> <Badge>{item.count}</Badge> </LinkContainer> ); }} /> );

#Selected

You can mark an item as selected by setting the selected prop.

const items = getItems(); items[15].selected = true; return ( <div style={{ height: "250px" }}> <ActionList items={items} /> </div> );

#Simple Pagination

return <ActionList items={getItems()} pageChanger={{}} />;

#Selected item in pagination

List will automatically paginate to a selected item.

const items = getItems(); items[8].selected = true; return <ActionList items={items} pageChanger={{}} />;

#Updating paginated items

Even if the items are updated, the list will still paginate to the selected item.

const [items, setItems] = useState(getItems()); return ( <> <Button onClick={() => { const selectedItem = Math.floor(Math.random() * items.length); setItems( items.map((item, i) => ({ ...item, selected: i === selectedItem, text: `Updated ${item.text}`, })) ); }} > Update items </Button> <ActionList items={items} pageChanger={{}} /> </> );

#External control of pagination

The pagination can be controlled from outside the component as well.

const [page, setPage] = useState(2); return ( <> <Button disabled={page === 1} onClick={() => setPage(1)}> Go to page 1 </Button> <Button disabled={page === 2} onClick={() => setPage(2)}> Go to page 2 </Button> <Button disabled={page === 3} onClick={() => setPage(3)}> Go to page 3 </Button> <Button disabled={page === 4} onClick={() => setPage(4)}> Go to page 4 </Button> <ActionList items={getItems()} pageChanger={{ page, onPageChange: (page) => console.log(`changed to page ${page}`) }} /> </> );

#Guidelines

#Best practices

  • ...
  • ...

#Do not use when

  • ...
  • ...

#Accessibility

This component comes with built-in accessibility, no extra work required.

Explore detailed guidelines for this component: Accessibility Specifications

#Writing

  • ...
  • ...